<?php
/**
 * 解析XML函数
 * @author wangtao
 * @version 2011.06.08
 */

class wt_xml
{
	private $set_time_limit = 0;
	private $xml;
	private $rss;
	public $blog = '';

	/**
	 * 初始化源
	 * @param string $rss
	 */
	public function __construct($rss)
	{
		$xmlstring = file_get_contents($rss);
		$charset = $this->getCharset($xmlstring);
		$charset = strtolower($charset);		#转换为小字
		$domain = $this->getDomain($rss);
		if ($charset != 'utf-8' && $domain == 'tianya.cn')
		{
			$xmlstring = iconv($charset, 'utf-8//IGNORE', $xmlstring);
			$xmlstring = str_replace('<?xml version="1.0" encoding="' . $charset . '"?>', 
			'<?xml version="1.0" encoding="utf-8"?>', $xmlstring);
		}
		if ($domain == 'infoq.com')
		{
			$xmlstring = str_replace('<dc:creator>', '<dcCreator>', $xmlstring);
			$xmlstring = str_replace('</dc:creator>', '</dcCreator>', $xmlstring);
			$xmlstring = str_replace('<dc:date>', '<dcDate>', $xmlstring);
			$xmlstring = str_replace('</dc:date>', '</dcDate>', $xmlstring);
		}

		$xml = new SimpleXMLElement($xmlstring, LIBXML_NOCDATA);

		if (empty($xml))
		{
			Log::writeLog($rss . '----------' . 'SimpleXMLElement！---'. date('Y.m.d H:i:s') . "\n", 'blogError');
			return ;
		}
		else
		{
			$this->xml = $xml;
			$this->rss = $rss;
		}
	}

	/**
	 * 得到RSS文档的字符编码
	 * @param string $xmlstring
	 */
	public function getCharset($xmlstring)
	{
		$header = substr($xmlstring, 0, 55);
		$arr = explode('encoding="', $header);
		if (empty($arr[1]))
		{
			return false;
		}
		$charset = explode('"', $arr[1]);
		return $charset[0];
	}

	/**
	 * 得到博客标题
	 */
	public function getBlogTitle()
	{
		$xml = $this->xml;
		$rss = $this->rss;
		$blogTitle = (string)$xml->channel->title;
		if (!empty($blogTitle))
		{
			return $blogTitle;
		}

		Log::writeLog($rss . '----------' . 'toBlogTitle！---'. date('Y.m.d H:i:s') . "\n", 'blogError');
		return ;
	}

	/**
	 * 得到博客链接
	 */
	public function getBlogLink()
	{
		$xml = $this->xml;
		$rss = $this->rss;
		#print_r($xml->channel->link);exit;
		$blogLink = (string)$xml->channel->link;
		if (!empty($blogLink))
		{
			return $blogLink;
		}

		Log::writeLog($rss . '----------' . 'toBlogLink！---'. date('Y.m.d H:i:s') . "\n", 'blogError');
		return ;
	}

	/**
	 * 得到博客备注信息
	 */
	public function getBlogDescription()
	{
		$xml = $this->xml;
		$rss = $this->rss;
		$blogDescription = (string)$xml->channel->description;
		if (!empty($blogDescription))
		{
			return $blogDescription;
		}
		/*if (empty($blogDescription))
		{
			Log::writeLog($rss . '----------' . 'description！---'. date('Y.m.d H:i:s') . "\n", 'blogError');
			return ;
		}
		return $blogDescription;*/
	}

	/**
	 * 得到博客最后更新日期
	 */
	public function getBlogLastBuildDate()
	{
		$xml = $this->xml;
		$rss = $this->rss;
		$lastBuildDate = (string)$xml->channel->lastBuildDate;
		if (!empty($lastBuildDate))
		{
			return $lastBuildDate;
		}
		$lastBuildDate = (string)$xml->channel->pubDate;
		if (!empty($lastBuildDate))
		{
			return $lastBuildDate;
		}
		/*$domain = $this->getDomain($rss);
		die($domain);*/
		
		Log::writeLog($rss . '----------' . 'lastBuildDate！---'. date('Y.m.d H:i:s') . "\n", 'blogError');
		return false;
	}

	/**
	 * 得到博客信息
	 */
	public function getPostInfo()
	{
		$xml		= $this->xml;
		$rss		= $this->rss;
		$postInfo	= $xml->xpath('/rss/channel/item');
		if (!empty($postInfo))	#如果获得信息为空，就记录错误信息
		{
			return $postInfo;
			
		}
		
		Log::writeLog($rss . '----------' . 'itemInfo！---'. date('Y.m.d H:i:s') . "\n", 'blogError');
		return ;
	}

	/**
	 * 得到博文详细信息
	 */
	public function getPostContentEncoded()
	{
		$xml				= $this->xml;
		$rss				= $this->rss;
		$postContentEncoded	= $xml->xpath('/rss/channel/item/content:encoded');
		if (!empty($postContentEncoded))
		{
			return $postContentEncoded;
		}
		$postContentEncoded	= $xml->xpath('/rss/channel/item/description');
		if (!empty($postContentEncoded))
		{
			return $postContentEncoded;
		}

		Log::writeLog($rss . '----------' . 'content:encoded！---'. date('Y.m.d H:i:s') . "\n", 'blogError');
		return ;
	}


	/**
	 * 得到博文作者信息
	 */
	public function getPostDcCreator()
	{
		$xml			= $this->xml;
		$rss			= $this->rss;
		$postDcCreator	= $xml->xpath('/rss/channel/item/dc:creator');
		if (!empty($postDcCreator))
		{
			return $postDcCreator;
		}
		$postDcCreator	= $xml->xpath('/rss/channel/item/author');
		if (!empty($postDcCreator))
		{
			return $postDcCreator;
		}

		$domain = $this->getDomain($rss);
		if ($domain == 'guokr.com' || $domain == 'cnbeta.com' || $domain == '163.com')
		{
			return $domain; #权益之计
		}
		$domains = array('feedsky.com', 'iteye.com', 'netnoease.com', 'codingnow.com', 'imququ.com');
		if (empty($postDcCreator) && in_array($domain, $domains))
		{
			$postDcCreator = $this->getBlogTitle();
			return $postDcCreator; 
		}

		Log::writeLog($rss . '----------' . 'dc:creator！---'. date('Y.m.d H:i:s') . "\n", 'blogError');
		return ;
	}

	/**
	 * 得到博客日志信息
	 */
	public function getPost()
	{
		$xml	= $this->xml;
		$rss	= $this->rss;
		$post	= array();

		$postInfo			= $this->getPostInfo();
		$postContentEncoded	= $this->getPostContentEncoded();
		$postDcCreator		= $this->getPostDcCreator();
		
		if (empty($postInfo) || empty($postContentEncoded) || empty($postDcCreator))	#如果资料不全，则返回false
		{
			return false;
		}

		foreach ($postInfo as $key=>$value)
		{
			$title		= $value->title;
			$link		= $value->link;
			$pubDate	= $value->pubDate;
			
			$post[] = array(
			'postTitle'				=>	(string)$value->title,
			'postLink'				=>	(string)$value->link,
			'postPubDate'			=>	(string)$value->pubDate,
			'postCreator'			=>	is_string($postDcCreator) ? $postDcCreator : (string)$postDcCreator[$key],
			'postContentEncoded'	=>	(string)$postContentEncoded[$key]
			);
		}
		#print_r($post);exit;
		return $post;
	}

	/**
	 * 返回RSS信息
	 */
	public function getRSS()
	{
		$rss	= $this->rss;
		$domain = $this->getDomain($rss);
		$data	= array();
		switch ($domain)
		{
			case 'ibuick.com'	: $data = $this->getFeedType();break;
			case 'infoq.com'	: $data = $this->getInfoq();break;
			default:
				$data['title']			= $this->getBlogTitle();
				$data['link']			= $this->getBlogLink();
				$data['description']	= $this->getBlogDescription();
				$data['lastBuildDate']	= $this->getBlogLastBuildDate();
				$data['post']			= $this->getPost();
		}
		return $data;
	}
	
	public function getInfoq()
	{
		$xml				= $this->xml;
		$post				= array();
		$data				= array();
		
		foreach ($xml->children() as $key=>$value)
		{
			$postInfo[] = $value;
		}
		
		$data['title'] = (string)$postInfo[0]->title;
		$data['link'] = (string)$postInfo[0]->link;
		$data['description'] = (string)$postInfo[0]->description;
		$data['lastBuildDate'] = NULL;
		unset($postInfo[0]);
		foreach ($postInfo as $key=>$value)
		{
			$post[] = array(
			'postTitle'				=>	(string)$value->title,
			'postLink'				=>	(string)$value->link,
			'postPubDate'			=>	(string)$value->dcDate,
			'postCreator'			=>	(string)$value->dcCreator,
			'postContentEncoded'	=>	(string)$value->description
			);
		}
		$data['post'] = $post;
		return $data;
	}

	/**
	 * 又一种解析方式
	 */
	public function getFeedType()
	{
		$xml				= $this->xml;
		$rss				= $this->rss;
		$feed				= array();
		$post				= array();
		#print_r($xml->children()->attributes()->href);exit;
		foreach($xml->children() as $key=>$child)
		{
			switch ($key)
			{
				case 'link':
					foreach ($child->attributes() as $k0=>$c0)
					{
						if ($k0 == 'href')
						{
							$feed['link'] = (string)$c0;
						}
					}break;
				case 'title' : $feed['title'] = (string)$child;break;
				case 'subtitle' : $feed['description'] = (string)$child;break;
				case 'updated' : $feed['lastBuildDate'] = (string)$child;break;
			}
			if (!empty($feed['link']))
			{
				break;
			}
		}
		foreach($xml->children() as $key=>$child)
		{
			foreach ($child->children() as $k=>$c)
			{
				switch ($k)
				{
					case 'author' : $dcCreator = (string)$c->name;break;
					case 'title' : $title = (string)$c;break;
					case 'link' :
						foreach ($c->attributes() as $k1=>$c1)
						{
							if ($k1 == 'href')
							{
								$link = (string)$c1;
							}
						}break;
					case 'published' : $pubDate = (string)$c;break;
					case 'content' : $contentEncoded = (string)$c;break;
				}
			}
			if (!empty($contentEncoded) && !in_array($contentEncoded, $post))
			{
				$post[] = array(
				'postTitle'				=>	$title,
				'postLink'				=>	$link,
				'postPubDate'			=>	$pubDate,
				'postCreator'			=>	$dcCreator,
				'postContentEncoded'	=>	$contentEncoded
				);
			}
  		}
  		$feed['post'] = $post;
  		return $feed;
	}

	public function getDomain($rss)
	{
		preg_match('/^(http:\/\/)?([^\/]+)/i', $rss, $matches);
		$host = $matches[2];
		preg_match('/[^\.\/]+\.[^\.\/]+$/', $host, $matches);
		if (isset($matches[0]))
		{
			return $matches[0];
		}
		else
		{
			return false;
		}
	}
}
